package com.xuecheng.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {

    private final TeachplanMediaMapper teachplanMediaMapper;
    private final TeachplanMapper teachplanMapper;

    /**
     * 获取课程信息树形结构数据
     *
     * @param courseId
     * @return
     */
    @Override
    public List<TeachplanDto> getTreeNodes(Long courseId) {

        List<TeachplanDto> list = teachplanMapper.selectTreeNodes(courseId);
        return list;
    }

    /**
     * 新增或修改课程计划
     *
     * @param saveTeachplanDto
     */
    @Override
    public void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {
        //通过有无id来判断是添加还是修改操作
        Long id = saveTeachplanDto.getId();
        if (id == null) {
            //添加操作
            Teachplan teachplan = BeanUtil.copyProperties(saveTeachplanDto, Teachplan.class);
            //设置创建时间
            teachplan.setCreateDate(LocalDateTime.now());

            int count = getTeachplanCount(teachplan.getCourseId(), teachplan.getParentid());
            teachplan.setOrderby(count + 1);
            //添加
            save(teachplan);
        } else {
            //修改操作
            Teachplan teachplan = getById(id);
            BeanUtil.copyProperties(saveTeachplanDto, teachplan);
            teachplan.setChangeDate(LocalDateTime.now());
            updateById(teachplan);
        }


    }

    /**
     * 删除课程计划分支
     *
     * @param id
     */
    @Override
    public void deleteTeachplan(Long id) {
        //查询实体
        Teachplan teachplan = getById(id);
        if (teachplan == null) {
            throw new XueChengPlusException("课程信息不存在");
        }
        Integer grade = teachplan.getGrade();
        if (grade == 1) {//大节点
            Integer count = lambdaQuery().eq(Teachplan::getParentid, teachplan.getId())
                    .eq(Teachplan::getCourseId, teachplan.getCourseId())
                    .count();
            if (count != 0) {
                throw new XueChengPlusException("课程计划信息还有子级信息，无法操作");
            }
            removeById(teachplan.getId());
        } else if (grade == 2) {//小节点
            boolean b = removeById(teachplan.getId());
            if (b) {
                //查询是否有媒资
                Integer count = teachplanMediaMapper.selectCount(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId, teachplan.getId()));
                if (count == 0) {
                    return;
                }
                //删除对应的媒资
                LambdaQueryWrapper<TeachplanMedia> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(TeachplanMedia::getTeachplanId, teachplan.getId());
                int i = teachplanMediaMapper.delete(wrapper);
                if (i <= 0) {
                    throw new XueChengPlusException("删除对应媒资信息失败");
                }
            }
        }
    }

    /**
     * 下移课程计划
     *
     * @param id
     */
    @Override
    public void moveDowm(Long id) {
        Teachplan teachplan = getById(id);
        if (teachplan == null) {
            throw new XueChengPlusException("课程计划不存在");
        }
        List<Teachplan> list = lambdaQuery().eq(Teachplan::getParentid, teachplan.getParentid())
                .eq(Teachplan::getCourseId, teachplan.getCourseId())
                .orderByAsc(Teachplan::getOrderby)
                .list();
        if (CollectionUtil.isNotEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                Teachplan teachplan1 = list.get(i);
                if (teachplan1.getId().equals(teachplan.getId())) {
                    Teachplan teachplan2 = null;
                    try {
                        teachplan2 = list.get(i + 1);
                    } catch (Exception e) {
                        throw new XueChengPlusException("这是最后一个");
                    }
                    Integer orderby = teachplan1.getOrderby();
                    teachplan1.setOrderby(teachplan2.getOrderby());
                    teachplan2.setOrderby(orderby);
                    //更新数据库
                    updateById(teachplan1);
                    updateById(teachplan2);
                    return;
                }
            }
            throw new XueChengPlusException("下移失败");
        }
    }

    /**
     * 上移课程计划
     *
     * @param id
     */
    @Override
    public void moveUp(Long id) {
        Teachplan teachplan = getById(id);
        if (teachplan == null) {
            throw new XueChengPlusException("课程计划不存在");
        }
        List<Teachplan> list = lambdaQuery().eq(Teachplan::getParentid, teachplan.getParentid())
                .eq(Teachplan::getCourseId, teachplan.getCourseId())
                .orderByAsc(Teachplan::getOrderby)
                .list();
        if (CollectionUtil.isNotEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                Teachplan teachplan1 = list.get(i);
                if (teachplan1.getId().equals(teachplan.getId())) {
                    Teachplan teachplan2 = null;
                    try {
                        teachplan2 = list.get(i - 1);
                    } catch (Exception e) {
                        throw new XueChengPlusException("这是第一个");
                    }
                    Integer orderby = teachplan1.getOrderby();
                    teachplan1.setOrderby(teachplan2.getOrderby());
                    teachplan2.setOrderby(orderby);
                    //更新数据库
                    updateById(teachplan1);
                    updateById(teachplan2);
                    return;
                }
            }
            throw new XueChengPlusException("上移失败");
        }
    }

    /**
     * 课程计划和媒资信息绑定
     *
     * @param bindTeachplanMediaDto
     */
    @Override
    @Transactional
    public void associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //查询课程计划表里面有没有相关数据
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("课程计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if (grade != 2) {
            XueChengPlusException.cast("只有二级节点才可以绑定媒资文件");
        }

        //课程标识
        Long courseId = teachplan.getCourseId();

        //首先删除原有的关系
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId, teachplanId));

        //之后插入更改后的关系
        TeachplanMedia teachplanMedia = BeanUtil.copyProperties(bindTeachplanMediaDto, TeachplanMedia.class);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMedia.setCourseId(courseId);
        teachplanMediaMapper.insert(teachplanMedia);
    }

    /**
     * 课程计划和媒资信息解除绑定
     *
     * @param teachPlanId
     * @param mediaId
     */
    @Override
    public void relieveAssociationMedia(Long teachPlanId, String mediaId) {
        //删除数据
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId, teachPlanId).eq(TeachplanMedia::getMediaId, mediaId));
    }

    /**
     * @param courseId 课程id
     * @param parentId 父课程计划id
     * @return int 最新排序号
     * @description 获取最新的排序号
     * @author Mr.M
     * @date 2022/9/9 13:43
     */
    private int getTeachplanCount(long courseId, long parentId) {
        Integer max = teachplanMapper.getMaxOrderBy(courseId, parentId);
        if (max == null) {
            max = 0;
        }
        return max;
    }



}
